#version 420 core

// 着色器输出
layout (location = 0) out vec4 frag;
// 颜色累积缓冲区
layout (binding = 0) uniform sampler2D accum;
// 可见性阈值缓冲区
layout (binding = 1) uniform sampler2D reveal;

// 极小值
const float EPSILON = 0.00001f;

// 精确计算浮点数的相等性
bool isApproximatelyEqual(float a, float b)
{
    return abs(a - b) <= (abs(a) < abs(b) ? abs(b) : abs(a)) * EPSILON;
}

// 获取三个值中的最大值
float max3(vec3 v)
{
    return max(max(v.x, v.y), v.z);
}

void main()
{
    // 片段坐标
    ivec2 coords = ivec2(gl_FragCoord.xy);

    // 片段可见性
    float revealage = texelFetch(reveal, coords, 0).r;

    // 如果没有透明片段，则节省混合和颜色纹理获取成本
    if (isApproximatelyEqual(revealage, 1.0f))
        discard;

    // 片段颜色
    vec4 accumulation = texelFetch(accum, coords, 0);

    // 抑制溢出
    if (isinf(max3(abs(accumulation.rgb))))
        accumulation.rgb = vec3(accumulation.a);

    // 防止浮点精度错误
    vec3 average_color = accumulation.rgb / max(accumulation.a, EPSILON);

    // 混合像素
    frag = vec4(average_color, 1.0f - revealage);
}